﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Netium.Compiler
{
    public class SymbolTable : ISymbolTable
    {
        private Dictionary<string, ISymbol> _symbols = new Dictionary<string, ISymbol>();

        public SymbolTable()
        {
        }

        public ISymbol Lookup(string symbolName)
        {
            if (string.IsNullOrEmpty(symbolName))
                throw new ArgumentException("Symbol name is empty or null.", "symbolName");

            if (_symbols.ContainsKey(symbolName))
                return _symbols[symbolName];

            return null;
        }

        public bool Contains(string symbolName)
        {
            if (string.IsNullOrEmpty(symbolName))
                throw new ArgumentException("Symbol name is empty or null.", "symbolName");

            return _symbols.ContainsKey(symbolName);
        }

        public void AddSymbol(ISymbol entry)
        {
            var symbolName = entry.Name;
            if (_symbols.ContainsKey(symbolName))
                throw new DuplicatedEntryException(symbolName);

            if (_symbols.ContainsValue(entry))
                throw new DuplicatedEntryException(symbolName);

            _symbols.Add(entry.Name, entry);
        }

        public void RemoveSymbol(string symbolName)
        {
            // Currently doesn't have any reason to remove a symbol from symbol table
            throw new NotSupportedException();
        }

        public ISymbol AllocateEntry(string symbolName)
        {
            if (!_symbols.ContainsKey(symbolName))
                this.AddSymbol(new Symbol(symbolName));

            return _symbols[symbolName];
        }

        public string[] SymbolNames
        {
            get {
                return _symbols.Keys.ToArray();
            }
        }

        public ISymbol[] Symbols 
        {
            get
            {
                return _symbols.Values.ToArray();
            }
        }
    }
}
